/**  
 * All rights Reserved, Designed By www.xiaozhanjiaoyu.cn
 * @Title:  NotifyObject.java   
 * @Package javaapplication.speechhandler   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: knight.lu     
 * @date:   2018年11月21日 下午2:50:41   
 * @version V1.0 
 * @Copyright: 2018 www.xiaozhanjiaoyu.cn Inc. All rights reserved. 
 * 
 */
package com.component;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.enu.ActionTypeEnum;
import com.nlp.baidu.UnitService;
import com.nls.speechhandler.CustomSpeechTranscriberListener;
import com.nls.speechhandler.RealSpeechRecognitionHandler;
import com.tts.speechsynthesizer.CustomSpeechSynthesizerListener;
import com.tts.speechsynthesizer.SpeechSynthesizeHandler;
import com.utils.PlayUtil;
import com.vo.AskAnswerText;
import com.vo.BDNLPResponse;
import com.vo.ResultJson;
import com.ws.segmentation.WordResult;
import com.ws.segmentation.WordSegmentationHandler;

import io.netty.util.internal.StringUtil;

/**   
 * @ClassName:  NotifyObject   
 * @Description: 通知器   
 * @author: knight.lu 
 * @date:   2018年11月21日 下午2:50:41   
 *     
 */
public class NotifyObject {
	
	private static Logger LOG = LoggerFactory.getLogger(NotifyObject.class);
	
	private File record;

	private ResultJson resultJson;
	
	private SpeechSynthesizeHandler synthesizeHandler;
	
	private RealSpeechRecognitionHandler recognitionHandler;
	
	private WordSegmentationHandler segmentationHandler;
	
	private javax.swing.JTextArea jTextArea1;
	
	//判断一次完成对话
	private String sessionId;
	
	private AskAnswerText askAnswerText;
	
	private String current_bot_id = BaiDuAuthService.BOT_ID;
	
//	private AudioPlayer player = AudioPlayer.player;
//	
//	private static int PlayStatus = 1;
	
	/**
	 * 通知标签
	 */
	public NotifyObject() {
		this.resultJson = new ResultJson();
	}
	
	public void setjTextArea1(javax.swing.JTextArea jTextArea1) {
		this.jTextArea1 = jTextArea1;
	}
	
	
	public void initSpeech() {
		this.askAnswerText = new AskAnswerText();
		this.askAnswerText.setAnswer(BaiDuAuthService.BOT_HELLO);
		notifySynthesuze();
	}
	
	/**
	 * 
	 * @Title: notifyRecognizeStart   
	 * @Description: 开始语音识别
	 * @author: knight.lu
	 * @param:       
	 * @return: void      
	 * @throws
	 */
	public void notifyRecognizeStart() {
		sessionId = null;
		initSpeech();
		notifyRecognize();
	}
	
	/**
	 * 
	 * @Title: notifyRecognizeEnd   
	 * @Description: 语音结束
	 * @author: knight.lu
	 * @param:       
	 * @return: void      
	 * @throws
	 */
	public void notifyRecognizeEnd() {
		recognitionHandler.shutdown();
	}
	
	
	
	public void notifyRecordStop() {
		if(recognitionHandler != null) {
			recognitionHandler.stop();
		}
	}
	
	public void notifyRecordStart() {
		if(recognitionHandler != null) {
			recognitionHandler.start();
		}
	}
	
	/**
	 * 
	 * @Title: notifyRecognized   
	 * @Description: 语音识别
	 * @author: knight.lu   
	 * @return: void      
	 * @throws
	 */
	public void notifyRecognize() {
		recognitionHandler = new RealSpeechRecognitionHandler(new CustomSpeechTranscriberListener(this));
		//recognitionHandler.analysis();
		recognitionHandler.analysis();
	}
	
	
	/**
	 * 
	 * @Title: notifyRecognized   
	 * @Description: 语音识别完成
	 * @author: knight.lu   
	 * @return: void      
	 * @throws
	 */
	public void notifyRecognized() {
		 if(! StringUtil.isNullOrEmpty(resultJson.getResult())) {
			LocalDateTime now = LocalDateTime.now();
			long ms = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
			this.resultJson.setuId(ms);
         	String formatStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
 			+ " : "+ resultJson.getResult() + System.lineSeparator();
         	//this.showLabel.setText(formatStr);
         	this.jTextArea1.append(formatStr);
         	log(formatStr);
         	//分词
         	//List<WordResult> list = notifyWordSegmentation(resultJson.getResult());
         	//询问机器人
         	this.askAnswerText = new AskAnswerText();
         	//this.askAnswerText.setAsk(resultJson.getResult());
         	notifyNLP();
         }
	}
	
	public void notifyNLP(){
		LOG.info("bot starting...");
		BDNLPResponse answer = UnitService.utterance(current_bot_id, sessionId,"0001", String.valueOf(this.resultJson.getuId()), this.resultJson.getResult());
		String ask = answer.getAsk();
		String asw = answer.getSay();
		//不同的状态做不同的回答
		if(ActionTypeEnum.BOT_ERROR.equals(answer.getActionType())) {
			//机器人错误
			askAnswerText.setAnswer(asw);
		}else if(ActionTypeEnum.FAILTURE.equals(answer.getActionType())){
			//识别意图失败，使用聊天机器人回答
			sessionId = null;
			current_bot_id = BaiDuAuthService.CHAT_BOT_ID;
			notifyNLP();
			return;
		} else if(ActionTypeEnum.SATISFY.equals(answer.getActionType())
				|| ActionTypeEnum.UNDERSTOOD.equals(answer.getActionType())
				|| ActionTypeEnum.CHAT.equals(answer.getActionType())) {
			//识别意图达到或者满意
			sessionId = null;
			Map<String,String> slots = answer.getMatchSlot();
			Set<String> set = slots.keySet();
	    	Iterator<String> it = set.iterator();
	    	while(it.hasNext()) {
	    		String sr = it.next();
	    		asw = asw.replaceAll("\\[D:"+ sr + "\\]", slots.get(sr));
	    		if(ask != null) {
	    			ask = ask.replaceAll("\\[D:"+ sr + "\\]", slots.get(sr));
	    		}
	    	}
	    	askAnswerText.setAnswer(asw);
	    	//如果当前机器人非默认机器人
	    	if(BaiDuAuthService.BOT_ID.equals(current_bot_id)) {
	    		//若存在意图引导主动询问机器人
	    		askAnswerText.setAsk(ask);
	    	}
		}else {
			//意图未达到
			sessionId = answer.getSessionId();
			Map<String,String> slots = answer.getMatchSlot();
			Set<String> set = slots.keySet();
	    	Iterator<String> it = set.iterator();
	    	while(it.hasNext()) {
	    		String sr = it.next();
	    		asw = asw.replaceAll("\\[D:"+ sr + "\\]", slots.get(sr));
	    	}
			askAnswerText.setAnswer(asw);
		}
		current_bot_id = BaiDuAuthService.BOT_ID;
		notifySynthesuze();
	}
	
	/**
	 * @throws InterruptedException 
	 * 
	 * @Title: notifySynthesuzer   
	 * @Description: 语音合成
	 * @author: knight.lu
	 * @param:       
	 * @return: void      
	 * @throws
	 */
	public void notifySynthesuze() {
		LOG.info("开始合成语音");
		SpeechSynthesizerListener listener = new CustomSpeechSynthesizerListener(this);
		synthesizeHandler = new SpeechSynthesizeHandler(listener);
		synthesizeHandler.process(this.askAnswerText.getAnswer());
	}
	
	/**
	 * @throws InterruptedException 
	 * 
	 * @Title: notifySynthesuzer   
	 * @Description: 通知语音合成完成
	 * @author: knight.lu
	 * @param:       
	 * @return: void      
	 * @throws
	 */
	public void notifySynthesuzed() {
        
		try {
			PlayUtil.play(this.resultJson.getPath());
			if(!StringUtil.isNullOrEmpty(this.askAnswerText.getAsk())) {
				this.resultJson.setResult(this.askAnswerText.getAsk());
				notifyNLP();
			}
//			FileInputStream fileau = null;
//			AudioStream as = null;
//			if(!player.isAlive()) {
//				LOG.info("文件路径："+this.resultJson.getPath());
//				fileau = new  FileInputStream(this.resultJson.getPath());
//				as = new AudioStream(fileau);
//				// AudioData data = as.getData();
//				// 循环播放 ContinuousAudioDataStream gg = new ContinuousAudioDataStream (data);
//				player.start(as);
//			}else {
//				notifyRecordStop();
//			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
		/*	try {
				//handler.shutdown();
				//AudioPlayer.player.stop(as);
				if(fileau != null) {
					fileau.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
			
		}
	}
	
	@Deprecated
	private List<WordResult> notifyWordSegmentation(String requestText) {
		segmentationHandler = new WordSegmentationHandler();
		return segmentationHandler.analysis(requestText);
	}
	
	public String readLog(int num){
		record = new File(CommonConstant.filePath 
        		+ File.separator+ LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".txt");
		if(!record.exists()) {
			return null;
		}
		BufferedReader br = null;
		InputStreamReader reader = null;
		String str = "";
		String result = "";
		try {
			reader = new InputStreamReader(new FileInputStream(record));
			br = new BufferedReader(reader);
			while((str=br.readLine()) != null) {
				result += (str + System.lineSeparator());
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				br.close();
				reader.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}
	
	 private void log(String line){
	    	record = new File(CommonConstant.filePath 
	        		+ File.separator+ LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".txt");
	    	if(!record.exists()) {
	    		try {
					record.createNewFile();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	    	}
	    	FileWriter ot = null;
			try {
				ot = new FileWriter(record,true);
				ot.append(line);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if(ot != null) {
					try {
						ot.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
	    }

	public ResultJson getResultJson() {
		return resultJson;
	}

	public void setResultJson(ResultJson resultJson) {
		this.resultJson = resultJson;
	}
	    
}
